
#include "MainWindow.h"
#include "VideoEncoder.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), m_nBandwidth(0), m_nCurTime(0)
{
	// Load media settings
	loadSettings();
	memset(m_nCurFrame, 0, 3 * sizeof(int));
	m_bPauseStreaming = 1;
	m_timer = new QTimer();
	m_timer->setInterval(1000);

	createInterface();

	// create connections
	m_lpStreamConnection = new StreamConnection();
	m_lpStreamEncoder = new StreamEncoder(m_audioChannels, m_audioSample, m_audioQuality, 
		m_videoFrameRates, m_wdgPreviewWidget->videoWidth(), m_wdgPreviewWidget->videoHeight(),
		m_videoQuality, m_videoBitRate, m_nKeyFrameShift, m_bDropFrame, m_bFastMode);
	m_lpIceCastHttp = new IceCastHttp();

	// create forms
	m_frmLogin = new LoginForm();
	m_frmLogin->setStyleSheet(styleSheet() + m_frmLogin->styleSheet());
	m_frmSettings = new MediaSettingForm();
	m_frmSettings->setStyleSheet(styleSheet() + m_frmSettings->styleSheet());

	//////////////////////////////////////////////////////////////////////////
	/// connect signals
	//////////////////////////////////////////////////////////////////////////

	// data encoded signal
	connect(m_lpStreamEncoder, SIGNAL(onProcessOggPage(const unsigned char*, const int, const unsigned char*, const int)),
		this, SLOT(onProcessOggPage(const unsigned char*, const int, const unsigned char*, const int)));
	connect(m_lpStreamEncoder, SIGNAL(onProcessVideoHeaders(PacketList*)), this, SLOT(onProcessVideoHeaders(PacketList*)));
	connect(m_lpStreamEncoder, SIGNAL(onProcessVideoPackets(PacketList*)), this, SLOT(onProcessVideoPackets(PacketList*)));
	// video captured signal
	connect(m_wdgPreviewWidget, SIGNAL(onCaptureVideo(const int, const int, const unsigned char *)),
		this, SLOT(onCaptureVideo(const int, const int, const unsigned char *)));
	// audio captured signal
	connect(m_wdgAudioWidget, SIGNAL(onCaptureAudio(const TYPE_SAMPLE_IN **, const int, const int, const int)),
		this, SLOT(onCaptureAudio(const TYPE_SAMPLE_IN **, const int, const int, const int)));
	// button login clicked
	connect(m_frmLogin, SIGNAL(onLogin(const char *, const char *, const char *)),
		this, SLOT(onLogin(const char *, const char *, const char *)));
	// button cancel clicked
	connect(m_frmLogin, SIGNAL(onCancel()), this, SLOT(onCancel()));
	// button refresh clicked
	connect(m_wdgControlWidget, SIGNAL(onUpdate()), this, SLOT(onUpdate()));
	// button start clicked
	connect(m_wdgControlWidget, SIGNAL(onStart()), this, SLOT(onStart()));
	// button stop clicked
	connect(m_wdgControlWidget, SIGNAL(onStop()), this, SLOT(onStop()));
	// button pause clicked
	connect(m_wdgControlWidget, SIGNAL(onPause()), this, SLOT(onPause()));
	// button resume clicked
	connect(m_wdgControlWidget, SIGNAL(onResume()), this, SLOT(onResume()));
	// button setting clicked
	connect(m_wdgControlWidget, SIGNAL(onShowSettings()), this, SLOT(onShowSettings()));
	// button save clicked
	connect(m_frmSettings, SIGNAL(onSaveSettings(const int, const int, const int, const int, const int, const int, const int, const int, const int, const int, const int)), 
		this, SLOT(onSaveSettings(const int, const int, const int, const int, const int, const int, const int, const int, const int, const int, const int)));
	// current session changed
	connect(m_wdgSessionWidget, SIGNAL(onCurrentSlotChanged(const IceCastSlot*)),
		this, SLOT(onCurrentSlotChanged(const IceCastSlot*)));
	// timer ticked
	connect(m_timer, SIGNAL(timeout()), this, SLOT(onTimer()));
	// video source control change
	connect(m_wdgVideoWidget, SIGNAL(onSourceChanged(const int)), this, SLOT(onVideoSourceChanged(const int)));
	// video source pause
	connect(m_wdgVideoWidget, SIGNAL(onPause(const bool)), this, SLOT(onVideoPaused(const bool)));
	// video source playback
	connect(m_wdgVideoWidget, SIGNAL(onPlayback(const bool)), this, SLOT(onVideoPlayback(const bool)));

#if DEBUG
	//////////////////////////////////////////////////////////////////////////
	// log message
	//////////////////////////////////////////////////////////////////////////
	connect(m_lpStreamConnection, SIGNAL(logged(const char*)), this, SLOT(onLog(const char *)));
	connect(m_lpStreamEncoder, SIGNAL(logged(const char*)), this, SLOT(onLog(const char *)));
	connect(m_wdgPreviewWidget, SIGNAL(logged(const char*)), this, SLOT(onLog(const char *)));
	connect(m_wdgAudioWidget, SIGNAL(logged(const char*)), this, SLOT(onLog(const char *)));
	connect(m_wdgControlWidget, SIGNAL(logged(const char*)), this, SLOT(onLog(const char *)));
	connect(m_wdgSessionWidget, SIGNAL(logged(const char*)), this, SLOT(onLog(const char *)));
#endif

	// start timer
	m_timer->start();

	// start encoding thread
	//m_lpStreamEncoder->start();

	// start streaming thread
	//m_lpStreamConnection->start();

	setWindowFlags(windowFlags() & ~Qt::WindowMaximizeButtonHint);
#if !defined(_WIN32) && !defined(_WIN64)
	setFixedWidth(440);
#else
	setFixedWidth(360);
#endif
}

MainWindow::~MainWindow()
{
	delete m_lpStreamEncoder;
	delete m_lpStreamConnection;
	delete m_lpIceCastHttp;

	delete m_frmLogin;
	delete m_frmSettings;
	delete m_timer;
}

void MainWindow::loadSettings()
{
	// Read configuration file
	QSettings setting(tr(SETTINGS_FILENAME), QSettings::IniFormat);
	setting.beginGroup(tr(SETTINGS_AUDIO));
	m_audioQuality = setting.value(tr(SETTINGS_QUALITY), 35).toInt();
	m_audioChannels = setting.value(tr(SETTINGS_CHANNEL), 1).toInt();
	m_audioSample = setting.value(tr(SETTINGS_RATE), 22050).toInt();
	setting.endGroup();

	setting.beginGroup(tr(SETTINGS_VIDEO));
	m_videoQuality = setting.value(tr(SETTINGS_QUALITY), 35).toInt();
	m_videoFrameRates = setting.value(tr(SETTINGS_FPS), 10).toInt();
	m_videoBitRate = setting.value(tr(SETTINGS_RATE), 98).toInt();
	m_nKeyFrameShift = setting.value(tr(SETTINGS_KFRAME_SHIFT), 90).toInt();
	m_bDropFrame = setting.value(tr(SETTINGS_DROPFRAME), 1).toInt();
	m_bFastMode = setting.value(tr(SETTINGS_FASTMODE), 1).toInt();
	m_bAutoBitRate = setting.value(tr(SETTINGS_AUTOBITRATE), 1).toInt();

	// 0: original, 1: 320x240, 2: 640x480
	int nSize = setting.value(tr(SETTINGS_VIDEO_SIZE), 1).toInt();
	switch (nSize)
	{
		case 0:
			m_videoWidth = 0;
			m_videoHeight = 0;
			break;
		case 1:
			m_videoWidth = 320;
			m_videoHeight = 240;
			break;
		case 2:
			m_videoWidth = 640;
			m_videoHeight = 480;
			break;
	}
	setting.endGroup();
}

void MainWindow::saveSettings()
{
	// Store configuration
	QSettings setting(tr(SETTINGS_FILENAME), QSettings::IniFormat);
	setting.beginGroup(tr(SETTINGS_AUDIO));
	setting.setValue(tr(SETTINGS_QUALITY), m_audioQuality);
	setting.setValue(tr(SETTINGS_CHANNEL), m_audioChannels);
	setting.setValue(tr(SETTINGS_RATE), m_audioSample);
	setting.endGroup();

	setting.beginGroup(tr(SETTINGS_VIDEO));
	setting.setValue(tr(SETTINGS_QUALITY), m_videoQuality);
	setting.setValue(tr(SETTINGS_FPS), m_videoFrameRates);
	setting.setValue(tr(SETTINGS_RATE), m_videoBitRate);
	setting.setValue(tr(SETTINGS_KFRAME_SHIFT), m_nKeyFrameShift);
	setting.setValue(tr(SETTINGS_DROPFRAME), m_bDropFrame);
	setting.setValue(tr(SETTINGS_FASTMODE), m_bFastMode);
	setting.setValue(tr(SETTINGS_AUTOBITRATE), m_bAutoBitRate);

	// 0: original, 1: 320x240, 2: 640x480
	int nSize = 1;
	switch (m_videoWidth)
	{
		case 0:
			nSize = 0;
			break;
		case 320:
			nSize = 1;
			break;
		case 640:
			nSize = 2;
			break;
	}
	setting.setValue(tr(SETTINGS_VIDEO_SIZE), nSize);
	setting.endGroup();
}

void MainWindow::createInterface()
{
	// create components
	QStatusBar *sbar = new QStatusBar();
	m_layMainLayout = new QVBoxLayout();
	m_wdgMainWidget = new QWidget();
	m_wdgPreviewWidget = new StreamPreviewWidget(0, m_videoFrameRates, m_videoWidth, m_videoHeight);
	m_wdgAudioWidget = new StreamAudioWidget(m_audioChannels, m_audioSample);
	m_wdgVideoWidget = new StreamVideoWidget();
	m_wdgDetailWidget = new StreamDetailWidget();
	m_wdgServerWidget = new StreamServerWidget();
	m_wdgControlWidget = new StreamControlWidget();
	m_wdgSessionWidget = new StreamSessionWidget();
	m_lblTitle = new QLabel(tr(LABEL_NO_PROVIDER));
	m_lblStatus = new QLabel(LABEL_STATUS_READY);
	m_lblStatus2 = new QLabel();
	m_lblStatus3 = new QLabel();

	// set properties
	m_wdgControlWidget->setStyleSheet(styleSheet());
	m_wdgSessionWidget->setStyleSheet(styleSheet());
	m_lblTitle->setStyleSheet("QLabel {font-size: 22px;}");
	m_wdgServerWidget->setVisible(false);
	m_wdgDetailWidget->setVisible(false);
	m_lblStatus->setFixedWidth(70);
	m_lblStatus3->setFixedWidth(85);

	// arrange components
	m_layMainLayout->addWidget(m_wdgPreviewWidget, 0, Qt::AlignCenter);
	m_layMainLayout->addWidget(m_lblTitle, 1, Qt::AlignCenter);
	m_layMainLayout->addWidget(m_wdgVideoWidget, 1, Qt::AlignCenter);
	m_layMainLayout->addWidget(m_wdgAudioWidget, 0, Qt::AlignCenter);
	m_layMainLayout->addWidget(m_wdgDetailWidget, 0, Qt::AlignCenter);
	m_layMainLayout->addWidget(m_wdgServerWidget, 0, Qt::AlignCenter);
	m_layMainLayout->addWidget(m_wdgSessionWidget, 0, Qt::AlignCenter);
	m_layMainLayout->addWidget(m_wdgControlWidget, 0, Qt::AlignCenter);
#if DEBUG
	m_txtLog = new QTextEdit();
	m_txtLog->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
	m_txtLog->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
	m_txtLog->setLineWrapMode(QTextEdit::WidgetWidth);
	m_txtLog->setFixedSize(320, 90);
	m_layMainLayout->addWidget(m_txtLog, 1, Qt::AlignCenter);
#endif
	m_wdgMainWidget->setLayout(m_layMainLayout);
	sbar->insertWidget(0, m_lblStatus);
	sbar->insertWidget(1, m_lblStatus2, 1);
	sbar->insertWidget(2, m_lblStatus3);

	// add all to current form
	this->setStatusBar(sbar);
	this->setCentralWidget(m_wdgMainWidget);
	this->setWindowTitle(tr(TITLE_FORM_MAIN));
	this->setStyleSheet(
		"MainWindow {background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #eef, stop: 1 #ccf);}"
		"LoginForm { background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #eef, stop: 1 #ccf);}"
		"QLineEdit {font: new courier; lineedit-password-character: 35; padding: 1px; border-style: solid; border: 1px solid gray; border-radius: 5px;}"
		"QPushButton {color: #DDDDDD; background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #88d, stop: 0.1 #99e, stop: 0.49 #77c, stop: 0.5 #66b, stop: 1 #77c); border-width: 1px; border-color: #339; border-style: solid; border-radius: 5; padding: 3px; font-size: 10px; padding-left: 5px; padding-right: 5px; min-width: 50px; min-height: 13px;}"
		"QPushButton:hover {color: #FFFFFF; background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #a8d, stop: 0.1 #b9e, stop: 0.49 #97c, stop: 0.5 #86b, stop: 1 #97c); border-width: 1px; border-color: #539; border-style: solid; border-radius: 5; padding: 3px; font-size: 10px; padding-left: 5px; padding-right: 5px; min-width: 50px; min-height: 13px;}"
		"QPushButton:disabled {color: #FFFFFF; background-color: gray; border-width: 1px; border-color: #539; border-style: solid; border-radius: 5; padding: 3px; font-size: 10px; padding-left: 5px; padding-right: 5px; min-width: 50px; min-height: 13px;}"
		"QGroupBox {font-weight: bold; margin-top: 7px; margin-bottom: 7px; padding: 0px; border: 1px solid; border-radius: 8px; border-color: #339}"
		"QGroupBox::title {top:-7 ex; left: 10px; subcontrol-origin: border; padding-left: 3px; padding-right: 3px;}"
		"QStatusBar {background-color: #EEEEEE;}"
		);
}

void MainWindow::onLogin(const char *url, const char * user, const char * pass)
{
	// check the url
	if (0 == url || strlen(url) == 0)
	{
		m_frmLogin->showMessage(MSG_LOGIN_EMPTY_URL);
		return;
	}

	// check the username and password
	if (0 == user || 0 == strlen(user) || 0 == pass || 0 == strlen(pass))
	{
		m_frmLogin->showMessage(MSG_LOGIN_EMPTY);
		return;
	}

	// connecting
	m_lpIceCastHttp->setBasedURL(url);
	int ret = m_lpIceCastHttp->login(user, pass);

	// check the result
	if (ret)
	{
		if (2 >= ret)
		{
			m_frmLogin->showMessage(MSG_LOGIN_CANNOT_CONN);
			return;
		}
		else
		{
			m_frmLogin->showMessage(MSG_LOGIN_INVALID_USR);
			return;
		}
	}

	// success, update slots information
	m_wdgSessionWidget->update(m_lpIceCastHttp->availableSlots(), m_lpIceCastHttp->nextSlot());

	// success, hide login form
	m_frmLogin->setVisible(false);
	setVisible(true);
}

void MainWindow::onCancel()
{
	m_frmLogin->close();
}

void MainWindow::onUpdate()
{
	if (m_lpIceCastHttp->refreshSlot())
		return;

	m_wdgSessionWidget->update(m_lpIceCastHttp->availableSlots(), m_lpIceCastHttp->nextSlot());
}

void MainWindow::onShowSettings()
{
	int nResolution = 1;
	if (0 == m_videoWidth)
		nResolution = 0;
	else if (640 == m_videoWidth)
		nResolution = 2;
	m_frmSettings->exec(m_audioQuality, m_audioChannels, m_audioSample, m_videoQuality, m_videoFrameRates, nResolution, m_videoBitRate, m_bAutoBitRate, m_nKeyFrameShift, m_bDropFrame, m_bFastMode);
}

void MainWindow::onSaveSettings(const int audioQuality, const int audioChannels, const int audioSample, const int videoQuality, const int videoFrameRates, const int nResolution, const int videoBitRate, const int autoBR, const int keyframeshift, const int dropframe, const int fastmode)
{
	int videoWidth = 0, videoHeight = 0;
	if (0 == nResolution)
		videoWidth = 0, videoHeight = 0;
	else if (2 == nResolution)
		videoWidth = 640, videoHeight = 480;
	else
		videoWidth = 320, videoHeight = 240;

	int bAudioChanged = 0, bVideoChanged = 0, bAllChanged = 0;
	if (m_audioChannels != audioChannels || m_audioSample != audioSample)
		bAudioChanged = 1, bAllChanged = 1;
	if (m_videoFrameRates != videoFrameRates || m_videoWidth != videoWidth || m_videoHeight != videoHeight)
		bVideoChanged = 1, bAllChanged = 1;
	if (m_audioQuality != audioQuality || 
		m_videoQuality != videoQuality || m_videoBitRate != videoBitRate ||
		m_nKeyFrameShift != keyframeshift || m_bDropFrame != dropframe || m_bFastMode != fastmode)
		bAllChanged = 1;

	m_audioQuality = audioQuality;
	m_audioChannels = audioChannels;
	m_audioSample = audioSample;
	m_videoQuality = videoQuality;
	m_videoFrameRates = videoFrameRates;
	m_videoBitRate = videoBitRate;
	m_nKeyFrameShift = keyframeshift;
	m_bDropFrame = dropframe;
	m_bFastMode = fastmode;
	m_videoWidth = videoWidth;
	m_videoHeight = videoHeight;
	m_bAutoBitRate = autoBR;

	m_frmSettings->accept();

	saveSettings();

	if (bAudioChanged)
		m_wdgAudioWidget->reset(m_audioChannels, m_audioSample);
	if (bVideoChanged)
		m_wdgPreviewWidget->reset(m_wdgVideoWidget->currentSource(), m_videoFrameRates, m_videoWidth, m_videoHeight);
	if (bAllChanged)
		m_lpStreamEncoder->reset(m_audioChannels, m_audioSample, m_audioQuality, m_videoFrameRates, m_wdgPreviewWidget->videoWidth(), m_wdgPreviewWidget->videoHeight(), m_videoQuality, m_videoBitRate, m_nKeyFrameShift, m_bDropFrame, m_bFastMode);
}

int MainWindow::showLogin()
{
	m_frmLogin->exec();
	if (m_frmLogin->isCancel())
		return 1;

	return 0;
}

void MainWindow::setVisible(bool visible)
{
	if (visible)
	{
		m_wdgPreviewWidget->setPaused(false);
		// start default input device
		m_wdgAudioWidget->startCaptureOnDevice();
	}
	else
	{
		m_wdgPreviewWidget->setPaused(true);
		m_wdgAudioWidget->stopCaptureOnDevice();
	}
	QMainWindow::setVisible(visible);
}

void MainWindow::onCaptureAudio(const TYPE_SAMPLE_IN **data, const int size, const int channels, const int sampleRate)
{
	if (!m_bPauseStreaming)
	{
		m_lpStreamEncoder->encodeAudio(data, size);
	}
}

void MainWindow::onCaptureVideo(const int width, const int height, const unsigned char *data)
{
	if (!m_bPauseStreaming)
	{
		if (m_nCurFrame[m_nCurTime] < m_videoFrameRates)
		{
			m_lpStreamEncoder->encodeVideo(data);
			m_nCurFrame[m_nCurTime]++;
		}
	}
}

void MainWindow::onProcessOggPage(const unsigned char* header, const int header_len,const unsigned char* data, const int size)
{
	m_lockProcessData.lock();
	if (m_lpStreamConnection->send(header, header_len, data, size) < 0)
	{
		m_nBandwidth = 0;

		// reconnect
		onStop();
		onStart();
	}

	m_nBandwidth += size;
	m_lockProcessData.unlock();
}

void MainWindow::onStart()
{
	IceCastSlot *curSlot = m_wdgSessionWidget->currentSlot();
	if (0 == curSlot)
		return;

#if TESTMODE
	if (curSlot->id == 0)
	{
		STR_CPY(curSlot->host, "192.168.167.131");
		curSlot->port = 8000;
		STR_CPY(curSlot->user, "source");
		STR_CPY(curSlot->pass, "hackme");
		STR_CPY(curSlot->mount, "mount.ogg");
	}
	else
#elif TESTMODE2
	if (curSlot->id == 0)
	{
		STR_CPY(curSlot->host, "173.230.245.3");
		curSlot->port = 8001;
		STR_CPY(curSlot->user, "nix");
		STR_CPY(curSlot->pass, "nixpass");
		STR_CPY(curSlot->mount, "app8001.ogg");
	}
	else
#endif
	if (m_lpIceCastHttp->initStream(curSlot))
	{
		QMessageBox::warning(this, tr("Connection failed"), tr("Cannot initialize stream. The session has been expired."));
		setVisible(false);
		showLogin();
		return;
	}

	m_wdgServerWidget->update(curSlot);
	m_lpStreamConnection->setHost(curSlot->host);
	m_lpStreamConnection->setPort(curSlot->port);
	m_lpStreamConnection->setUser(curSlot->user);
	m_lpStreamConnection->setPass(curSlot->pass);
	m_lpStreamConnection->setMountPoint(curSlot->mount);

	if (m_lpStreamConnection->connectShout())
	{
		QMessageBox::warning(this, tr("Connection failed"), tr("Cannot connect to IceCast Server."));
		m_wdgServerWidget->reset();
		m_wdgControlWidget->setReady(true);
		return;
	}

	m_wdgVideoWidget->enablePlayback(true);
	m_wdgSessionWidget->enableSelecting(false);
	m_lblStatus->setText(LABEL_STATUS_CONNECTED);

	m_lpStreamEncoder->reset(m_audioChannels, m_audioSample, m_audioQuality, m_videoFrameRates, 
		m_wdgPreviewWidget->videoWidth(), m_wdgPreviewWidget->videoHeight(), m_videoQuality, 
		m_videoBitRate, m_nKeyFrameShift, m_bDropFrame, m_bFastMode);
	m_lpStreamEncoder->encodeHeader();
	m_bPauseStreaming = 0;
}

void MainWindow::onStop()
{
	m_bPauseStreaming = 1;
	m_lpStreamEncoder->encodeRemain();
	m_wdgServerWidget->reset();

	m_lpStreamConnection->close();
	m_lblStatus->setText(LABEL_STATUS_READY);
	m_lblStatus2->setText("");
	m_nBandwidth = 0;

	m_wdgVideoWidget->enablePlayback(false);
	m_wdgSessionWidget->enableSelecting(true);
	IceCastSlot *curSlot = m_wdgSessionWidget->currentSlot();
	if (0 == curSlot)
		return;
	m_lpIceCastHttp->freeStream(curSlot);
}

void MainWindow::onResume()
{
	m_lblStatus->setText(LABEL_STATUS_CONNECTED);
	m_bPauseStreaming = 0;
}

void MainWindow::onPause()
{
	m_lblStatus->setText(LABEL_STATUS_PAUSED);
	m_bPauseStreaming = 1;
}

void MainWindow::closeEvent(QCloseEvent *)
{
	onStop();
}

void MainWindow::onTimer()
{
	QDateTime gmtDateTime = QDateTime::currentDateTime().toTimeSpec(Qt::UTC);
	QDateTime estDateTime = gmtDateTime.addSecs(-(5*60*60));
	m_lblStatus3->setText(estDateTime.toString("MMM dd, hh:mm:ss"));

	if (!m_bPauseStreaming)
	{
		double avg = (m_nCurFrame[0] + m_nCurFrame[1] + m_nCurFrame[2]) / 3.0;
		m_nCurTime = estDateTime.time().second() % 3;
		m_nCurFrame[m_nCurTime] = 0;
		if (m_nBandwidth < 100000)
			m_lblStatus2->setStyleSheet("QLabel {color: red;}");
		else
			m_lblStatus2->setStyleSheet("");
		m_lblStatus2->setText("<b>Sent:</b> " + QString::number(m_nBandwidth) + " - <b>FPS:</b> " + QString::number(avg, 'g', 5));
	}
}

void MainWindow::onCurrentSlotChanged(const IceCastSlot *slot)
{
	if (slot)
	{
		m_lblTitle->setText(slot->provider_name);
		m_wdgControlWidget->setReady(true);
	}
	else
	{
		m_lblTitle->setText(tr(LABEL_NO_PROVIDER));
		m_wdgControlWidget->setReady(false);
	}
}

#if DEBUG
void MainWindow::onLog(const char *msg)
{
	m_txtLog->append(msg);
}
#endif

void MainWindow::onVideoSourceChanged(const int index)
{
	m_wdgPreviewWidget->reset(index, m_videoFrameRates, m_videoWidth, m_videoHeight);
}

void MainWindow::onVideoPlayback(const bool bPlayback)
{
	m_wdgPreviewWidget->setPlayback(bPlayback);
}

void MainWindow::onVideoPaused(const bool bPaused)
{
	m_wdgPreviewWidget->setPaused(bPaused);
}

void MainWindow::onProcessVideoHeaders(PacketList *packets)
{
	m_wdgPreviewWidget->resetDecoder(packets);
}

void MainWindow::onProcessVideoPackets(PacketList *packets)
{
	if (m_wdgPreviewWidget->isPlayback())
		m_wdgPreviewWidget->decodePackets(packets);
}

